﻿using System;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Collections;
using System.Text;
using System.IO;
using Microsoft.Win32;
using System.Windows.Forms;

namespace MediaRemoteServer
{
    class Program
    {
        public const int PORT = 8241;

        private static ArrayList clients;
        private static bool continueReclaim;
        private static bool continueListening;

        static void Main(string[] args)
        {
            #region test code
            /*string[] drives = Directory.GetLogicalDrives();
            for (int ii = 0; ii < drives.Length; ii++)
            {
                Console.WriteLine("Drive: {0}", drives[ii]);
            }
            Console.ReadKey();
            return;*/

            /*string japan = "D:\\Share\\Formula 1\\2009\\15 Japan\\2009 Japanese Grand Prix Race Edit.flv";
            string abuDhabi = "D:\\Share\\Formula 1\\2009\\17 Abu Dhabi\\2009 Abu Dhabi Grand Prix Race Edit.flv";

            Playlist playlist = new Playlist();
            playlist.addItem(japan);
            playlist.addItem(abuDhabi);

            MediaControl player = new MediaControl();
            player.setPlaylist(playlist);

            bool run = true;
            while (run)
            {
                ConsoleKeyInfo info = Console.ReadKey(true);
                switch (info.KeyChar)
                {
                    case 'p':
                        player.play();
                        break;
                    case ' ':
                        player.pause();
                        break;
                    case 'n':
                        player.next();
                        break;
                    case 'r':
                        player.previous();
                        break;
                    case 's':
                        player.stop();
                        break;
                    case 'q':
                        run = false;
                        break;
                    default: break;
                }
            }

            return;*/

            /*byte[] data = listFiles("C:\\");
            MemoryStream stream = new MemoryStream(data);

            byte[] numFileByt = new byte[sizeof(int)];
            stream.Read(numFileByt, 0, numFileByt.Length);
            int numFiles = BitConverter.ToInt32(numFileByt, 0);

            Console.WriteLine("Num files in list: {0}", numFiles);

            for (int ii = 0; ii < numFiles; ii++)
            {
                byte[] strLenByt = new byte[sizeof(int)];
                stream.Read(strLenByt, 0, strLenByt.Length);
                int strLen = BitConverter.ToInt32(strLenByt, 0);

                byte[] strByt = new byte[strLen];
                stream.Read(strByt, 0, strByt.Length);
                string str = Encoding.UTF8.GetString(strByt);

                Console.WriteLine(str);
            }

            Console.ReadKey();
            return;*/




            /*byte[] buffer = new byte[1];
            TcpListener tcpListener = new TcpListener(IPAddress.Any, 8241);
            tcpListener.Start();

            while (true)
            {
                Socket serverSocket = tcpListener.AcceptSocket();

                buffer[0] = (byte)VolumeControl.getVolumePercent();
                serverSocket.Send(buffer);

                while (serverSocket.Connected)
                {
                    serverSocket.Receive(buffer);
                    switch (buffer[0])
                    {
                        case COMMAND_KEEP_ALIVE:
                            break;
                        case COMMAND_SET_SYSTEM_VOLUME:
                            serverSocket.Receive(buffer);
                            VolumeControl.setVolumePercent(buffer[0]);
                            buffer[0] = (byte)VolumeControl.getVolumePercent();
                            serverSocket.Send(buffer);
                            break;
                        case COMMAND_EXIT:
                            serverSocket.Close();
                            break;
                        case COMMAND_PLAY:
                            player.play();
                            break;
                        case COMMAND_PREVIOUS:
                            player.previous();
                            break;
                        case COMMAND_PAUSE:
                            player.pause();
                            break;
                        case COMMAND_NEXT:
                            player.next();
                            break;
                        case COMMAND_STOP:
                            player.stop();
                            break;
                        case COMMAND_SET_FULLSCREEN:
                            player.setFullScreen(player.isFullScreen() ? false : true);
                            break;
                    }
                }
            }*/
            #endregion

            checkForUpdate();

            string installDir = null;
            RegistryKey videoLan = Registry.LocalMachine.OpenSubKey("SOFTWARE\\VideoLAN");
            if (videoLan != null)
            {
                RegistryKey vlc = videoLan.OpenSubKey("VLC");
                if (vlc != null)
                {
                    installDir = (string)vlc.GetValue("InstallDir");
                    if (installDir == null)
                    {
                        Console.WriteLine("Could not find the location of VLC. InstallDir");
                        Console.ReadKey(true);
                        return;
                    }
                }
                else
                {
                    Console.WriteLine("Could not find the location of VLC. VLC");
                }
            }
            else
            {
                Console.WriteLine("Could not find the location of VLC. VideoLAN");
            }

            Directory.SetCurrentDirectory(installDir);

            clients = new ArrayList();

            //Playlist playlist = new Playlist();
            //playlist.addItem("Z:\\Downloads\\NCIS.Los.Angeles.S01E14.LD50.HDTV.XviD-FQM.[VTV].avi");
            //playlist.addItem("Z:\\TV\\Caprica\\Caprica.S01E01.Pilot.HDTV.XviD-FQM.[VTV].avi");
            //playlist.addItem("Z:\\Downloads\\Caprica.S01E02.Rebirth.HDTV.XviD-FQM.[VTV].avi");
            MediaControl player = new MediaControl(installDir);
            //player.setPlaylist(playlist);

            continueReclaim = true;
            Thread reclaimThread = new Thread(new ThreadStart(reclaim));
            reclaimThread.Start();

            continueListening = true;
            TcpListener tcpListener = new TcpListener(IPAddress.Any, PORT);
            tcpListener.Start();

            while (continueListening)
            {
                TcpClient client = tcpListener.AcceptTcpClient();

                lock (clients.SyncRoot)
                {
                    int ii = clients.Add(new ClientHandler(client, player));
                    ((ClientHandler)clients[ii]).start();
                }
            }

        }

        private static void checkForUpdate()
        {
            try
            {
                int currentVersion = 3;

                WebClient client = new WebClient();
                Console.WriteLine("Checking for updates\nCurrent version: " + currentVersion);
                string sNewestVersion = client.DownloadString("http://www.bencordingley.com/update/RemoteControl/server");
                int newestVersion = int.Parse(sNewestVersion);
                Console.WriteLine("Newest version: " + newestVersion);
                if (newestVersion > currentVersion)
                {
                    Console.WriteLine("Do you want to download the new version? [y/n]");
                    ConsoleKeyInfo key = Console.ReadKey();
                    if (key.KeyChar == 'y' || key.KeyChar == 'Y')
                    {
                        Console.WriteLine("\nDownloading new version to desktop");

                        using (SaveFileDialog fileDiag = new SaveFileDialog())
                        {
                            fileDiag.AddExtension = true;
                            fileDiag.DefaultExt = "exe";
                            fileDiag.FileName = "RemoteControl.exe";
                            fileDiag.Filter = "Windows Executable (.exe)|*.exe";
                            if (fileDiag.ShowDialog() == DialogResult.OK)
                            {
                                string destination = fileDiag.FileName;//Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\remote_server.exe";
                                client.DownloadFile("http://www.bencordingley.com/VolumeControlServer.exe", destination);
                                Console.WriteLine("Download complete.");
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine("Will bug you about it next time");
                    }
                }
                else
                {
                    Console.WriteLine("Up to date.");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception occured checking for an update.\n" + ex);
            }
        }

        private static void reclaim()
        {
            while (continueReclaim)
            {
                lock (clients.SyncRoot)
                {
                    for (int x = clients.Count - 1; x >= 0; x--)
                    {
                        Object client = clients[x];
                        if (!((ClientHandler)client).isAlive())
                        {
                            clients.Remove(client);
                        }
                    }
                }
                Thread.Sleep(200);
            }
        }

    }
}
